package com.atyuntuku.yuntuku.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.atyuntuku.yuntuku.controller.request.PictureEditRequest;
import com.atyuntuku.yuntuku.controller.request.PictureQueryRequest;
import com.atyuntuku.yuntuku.controller.request.PictureUpdateRequest;
import com.atyuntuku.yuntuku.dto.file.PictureUploadRequest;
import com.atyuntuku.yuntuku.dto.file.UploadPictureResult;
import com.atyuntuku.yuntuku.exception.ErrorCode;
import com.atyuntuku.yuntuku.exception.ThrowUtils;
import com.atyuntuku.yuntuku.manager.FileManager;
import com.atyuntuku.yuntuku.mapper.PictureMapper;
import com.atyuntuku.yuntuku.pojo.Picture;
import com.atyuntuku.yuntuku.pojo.User;
import com.atyuntuku.yuntuku.service.PictureService;
import com.atyuntuku.yuntuku.service.UserService;
import com.atyuntuku.yuntuku.utils.CommonUtils;
import com.atyuntuku.yuntuku.vo.PictureVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.http.HttpClientConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: PictureServiceIMpl
 * Package: com.atyuntuku.yuntuku.service.impl
 * Description:
 *
 * @Author qinglong wei
 * @Create 2025/10/11 11:51
 * @Version 1.0
 */
@Service
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture> implements PictureService {

    @Resource
    FileManager fileManager;

    @Autowired
    UserService userService;

    @Override
    public PictureVO uploadPicture(MultipartFile multipartFile, PictureUploadRequest pictureUploadRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(multipartFile == null, ErrorCode.PARAMS_ERROR, "参数不能为空");
        User currentUser = CommonUtils.getCurrentUser(request);
        Long pictureId = null;
        System.out.println("pictureUploadRequest = "+JSONUtil.toJsonStr(pictureUploadRequest));
        if (pictureUploadRequest != null && pictureUploadRequest.getId()!=null) {
            Long id = pictureUploadRequest.getId();
            ThrowUtils.throwIf( id<= 0 , ErrorCode.PARAMS_ERROR, "请求参数错误");
            pictureId = pictureUploadRequest.getId();
        }

        //不为null说明是进行更新，进入数据库查看之前的信息
        if (pictureId != null) {
            Picture picture = this.getById(pictureId);
            ThrowUtils.throwIf(picture == null, ErrorCode.PARAMS_ERROR, "无法找到当前图片");
        }
        String uploadPrefix = String.format("public/%s", currentUser.getId());
        UploadPictureResult uploadpicture = fileManager.uploadpicture(multipartFile, uploadPrefix);
        String url = uploadpicture.getUrl();
        String picName = uploadpicture.getPicName();
        Long picSize = uploadpicture.getPicSize();
        int picWidth = uploadpicture.getPicWidth();
        int picHeight = uploadpicture.getPicHeight();
        Double picScale = uploadpicture.getPicScale();
        String picFormat = uploadpicture.getPicFormat();
        Picture picture = new Picture();

        picture.setUrl(url);
        picture.setPictureName(picName);
        picture.setPicSize(picSize);
        picture.setPicWidth(picWidth);
        picture.setPicHeight(picHeight);
        picture.setPicScale(picScale);
        picture.setPicFormat(picFormat);
        picture.setUserId(currentUser.getId());
        picture.setIsDeleted(0);

        if (pictureId != null) {
            picture.setId(pictureId);
            picture.setEditTime(new Date());
        }

        boolean flag = this.saveOrUpdate(picture);
        ThrowUtils.throwIf(!flag,ErrorCode.SYSTEM_ERROR,"系统错误，请重试");
        return PictureVO.objToVo(picture);
    }

    @Override
    public QueryWrapper<Picture> getQueryWrapper(PictureQueryRequest pictureQueryRequest) {
        {
            Long id = pictureQueryRequest.getId();
            String name = pictureQueryRequest.getPictureName();
            String introduction = pictureQueryRequest.getIntroduction();
            String category = pictureQueryRequest.getCategory();
            List<String> tags = pictureQueryRequest.getTags();
            Long picSize = pictureQueryRequest.getPicSize();
            Integer picWidth = pictureQueryRequest.getPicWidth();
            Integer picHeight = pictureQueryRequest.getPicHeight();
            Double picScale = pictureQueryRequest.getPicScale();
            String picFormat = pictureQueryRequest.getPicFormat();
            String searchText = pictureQueryRequest.getSearchText();
            Long userId = pictureQueryRequest.getUserId();
            String sortField = pictureQueryRequest.getSortField();
            String sortOrder = pictureQueryRequest.getSortOrder();

            QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(ObjectUtil.isNotEmpty(id),"id",id);
            queryWrapper.eq(ObjectUtil.isNotEmpty(category),"category",category);
            queryWrapper.ge(ObjectUtil.isNotEmpty(picWidth),"pic_width",picWidth);
            queryWrapper.ge(ObjectUtil.isNotEmpty(picHeight),"pic_height",picHeight);
            queryWrapper.eq(ObjectUtil.isNotEmpty(picScale),"pic_scale",picScale);
            queryWrapper.eq(ObjectUtil.isNotEmpty(picFormat),"pic_format",picFormat);
            queryWrapper.and(ObjectUtil.isNotEmpty(searchText),qw->qw.like("picture_name",searchText).or()
                    .like("introduction",searchText));

           if (CollectionUtil.isNotEmpty(tags))
           {
               for(String tag : tags )
               {
                   queryWrapper.like("tags",tag);
               }
           }
            queryWrapper.orderBy(ObjectUtil.isNotEmpty(sortField),"ascend".equals(sortField),sortField);
           return queryWrapper;
        }
    }

    @Override
    public Page<PictureVO> getPicturePage(PictureQueryRequest pictureQueryRequest) {
        //校验参数
        ThrowUtils.throwIf(pictureQueryRequest == null,ErrorCode.PARAMS_ERROR,"参数不能为空");
        int current = pictureQueryRequest.getCurrent();
        int pageSize = pictureQueryRequest.getPageSize();
        ThrowUtils.throwIf(pageSize>20,ErrorCode.PARAMS_ERROR,"查询页面大小不能超过20条每页");//防止爬虫
        //查询图片列表
        Page<Picture> pages = this.page(new Page<>(current, pageSize), getQueryWrapper(pictureQueryRequest));
        return this.getPictureVo(pages);
    }

    @Override
    public Page<PictureVO> getPictureVo(Page<Picture> pages) {
        //创建一个页面大小相同的页面
        Page<PictureVO> pictureVOPage = new Page<>(pages.getCurrent(),pages.getSize(),pages.getTotal());
        List<Picture> pictureList = pages.getRecords();

        //空页面就返回
        if(CollectionUtil.isEmpty(pictureList))
        {
            return pictureVOPage;
        }

        //转为图片对象的VO
        List<PictureVO> pictureVOList = pictureList.stream().map(PictureVO::objToVo).collect(Collectors.toList());

        //接下里分表查询图片创建者信息
        Set<Long> ids = pictureList.stream().map(Picture::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> listMap = userService.listByIds(ids).stream().collect(Collectors.groupingBy(User::getId));
        pictureVOList.stream().forEach(pictureVO -> {
            if(listMap.containsKey(pictureVO.getUserId()))
            {
                Long userId = pictureVO.getUserId();
                User user = listMap.get(userId).get(0);
                pictureVO.setUser(userService.getUserVo(user));
            }
        });
        pictureVOPage.setRecords(pictureVOList);
        return pictureVOPage;
    }

    @Override
    public void validate(Picture picture) {
        ThrowUtils.throwIf(picture == null, ErrorCode.PARAMS_ERROR);
        // 从对象中取值
        Long id = picture.getId();
        String url = picture.getUrl();
        String introduction = picture.getIntroduction();
        // 修改数据时，id 不能为空，有参数则校验
        ThrowUtils.throwIf(ObjUtil.isNull(id), ErrorCode.PARAMS_ERROR, "id 不能为空");
        if (StrUtil.isNotBlank(url)) {
            ThrowUtils.throwIf(url.length() > 1024, ErrorCode.PARAMS_ERROR, "url 过长");
        }
        if (StrUtil.isNotBlank(introduction)) {
            ThrowUtils.throwIf(introduction.length() > 800, ErrorCode.PARAMS_ERROR, "简介过长");
        }
    }

    @Override
    public Boolean updatePicture(PictureUpdateRequest pictureUpdateRequest) {
        ThrowUtils.throwIf(pictureUpdateRequest == null,ErrorCode.PARAMS_ERROR,"更新请求为空");

        Picture picture = new Picture();
        BeanUtil.copyProperties(pictureUpdateRequest,picture);
        //校验一下picture里的参数合法性
        validate(picture);
        List<String> tags = pictureUpdateRequest.getTags();

        //注意存入数据库必须把集合转成java里的json字符串
        String tagstr = null;
        if (CollectionUtil.isNotEmpty(tags))
        {
            tagstr = JSONUtil.toJsonStr(tags);
        }

        picture.setTags(tagstr);

        //查询数据库有没有
        Long id = picture.getId();
        Picture oldpicture = this.getById(id);
        ThrowUtils.throwIf(oldpicture == null,ErrorCode.NOT_FOUND_ERROR);
         picture.setUpdateTime(new Date());

        //更新数据库
        boolean flag = this.updateById(picture);
        ThrowUtils.throwIf(!flag,ErrorCode.SYSTEM_ERROR,"系统错误，请联系管理员");
        return flag;
    }

    @Override
    public Boolean editPicture(PictureEditRequest pictureEditRequest,HttpServletRequest request) {
        //校验参数
        ThrowUtils.throwIf(pictureEditRequest == null || pictureEditRequest.getId() <=0,ErrorCode.PARAMS_ERROR,"参数错误");
        Long id = pictureEditRequest.getId();

        User currentUser = CommonUtils.getCurrentUser(request);
         ThrowUtils.throwIf(currentUser == null ,ErrorCode.NOT_LOGIN_ERROR,"请登录后重试");


        Picture picture = this.getById(id);

        //权限校验，编辑图片要么是本人，要么是管理员
        ThrowUtils.throwIf(picture.getUserId()!= currentUser.getId()&&!CommonUtils.isAdmin(currentUser),ErrorCode.NO_AUTH_ERROR);
        Picture newPicture = new Picture();
        BeanUtil.copyProperties(pictureEditRequest,newPicture);
        newPicture.setTags(JSONUtil.toJsonStr(pictureEditRequest.getTags()));
        newPicture.setEditTime(new Date());
        boolean flag = this.updateById(newPicture);
        return flag;
    }

}
